<?php
namespace core\models;
/**
 * 用Mysql储存的缓存
 * Class Cache_Mysql
 * 【注意】此类已经在Cache::open()中被调用，不用直接new。
 * @author ZhouHaoHua <53027327@qq.com> by 2014-04-01
 */
class Cache_Mysql implements Interface_Cache {
    private $db;
    private static $cache_table = 'cache';
    /**
     * 本类总开关
     * @var bool false为关，true为开
     */
    private static $Switch = true;
    /**
     * key标签头
     * @var string
     */
    private $key_life_tag;

    public function __construct () {
        $this->key_life_tag = Z_APP . Z_TOP_WWW;
        $this->db = Database_Action::getDb(/*Database::openDatabase('Mysqli', DB_SERVER, DB_SERVER_USERNAME, DB_SERVER_PASSWORD, DB_DATABASE)*/);
        //创建后就不用检查表了，浪费时间的
        /*if (!$this->db->table_exists(self::$cache_table)) {
            $this->c_table();
        }*/
    }

    /**
     * 创建缓存表结构
     */
    private function c_table () {
        if(!self::$Switch) return false;
        $sql =
            "CREATE TABLE IF NOT EXISTS " . self::$cache_table . " (
			  `c_key` char(32) NOT NULL COMMENT 'md5格式的键值',
			  `c_value` LONGTEXT NOT NULL COMMENT '保存的值',
			  `c_expire` int(11) NOT NULL COMMENT '到期时间',
			  PRIMARY KEY  (`c_key`)
			) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='缓存表';";
        $this->db->query($sql);
    }

    public function connect ($server, $port) {
        //这个方法不做任何动作！
    }

    /**
     * 增加一个条目到缓存
     * @param string $key 将要分配给变量的key
     * @param string|array $var 将要被存储的变量值。
     * @param int    $flag 使用MEMCACHE_COMPRESSED标记对数据进行压缩(使用zlib)
     * @param int    $expire 有效期秒。
     *
     * @return bool 成功时返回 true， 或者在失败时返回 false。 如果这个key已经存在返回false。
     */
    public function add ($key, $var, $flag = MEMCACHE_COMPRESSED, $expire = 2592000) {
        if(!self::$Switch) return false;
        $key .= $this->key_life_tag;
        $expire = (int)$expire;
        $str = 'REPLACE INTO ' . self::$cache_table . ' SET c_key="' . md5($key) . '", c_value="' . base64_encode(serialize($var)) . '", c_expire="' . (time() + $expire) . '" ';
        $this->db->query($str);
        return true;
    }

    /**
     * 保存数据到缓存
     * @param string $key 将要分配给变量的key
     * @param array|string|int    $var 将要被存储的变量。
     * @param int    $flag 使用MEMCACHE_COMPRESSED标记对数据进行压缩(使用zlib)
     * @param int    $expire 有效期秒。
     *
     * @return bool 成功时返回 true， 或者在失败时返回 false。 如果这个key已经存在返回false。
     */
    public function set ($key, $var, $flag = 0, $expire = 2592000) {
        if(!self::$Switch) return false;
        return $this->add($key, $var, $flag, $expire);
    }

    /**
     * 取得一条缓存数据
     * @param string $key 要获取值的key
     * @param bool   $flags
     * @return int|mixed|string
     */
    public function get ($key, &$flags = false) {
        if(!self::$Switch) return false;
        $key .= $this->key_life_tag;
        $data = $this->db->getFieldValue('c_value', self::$cache_table, 'c_key="' . md5($key) . '" and c_expire > "' . time().'" ');
        if ($data) {
            $data = unserialize(base64_decode($data));
        }
        return $data;
    }

    /**
     * 替换一条缓存记录
     * @param string $key 要替换的key
     * @param        $var 新值
     * @param int    $flag 使用MEMCACHE_COMPRESSED标记对数据进行压缩(使用zlib)
     * @param int    $expire $expire 有效期秒
     *
     * @return bool
     */
    public function replace ($key, $var, $flag = 0, $expire = 2592000) {
        if(!self::$Switch) return false;
        $key .= $this->key_life_tag;
        $expire = ($expire == '0' ? 2592000 : (int)$expire);
        $this->db->query('UPDATE ' . self::$cache_table . ' SET c_value="' . base64_encode(serialize($var)) . '", c_expire="' . (time() + $expire) . '" WHERE c_key="' . md5($key) . '" ');
        return true;
    }

    /**
     * 清空缓存数据
     */
    public function flush () {
        $this->db->query('TRUNCATE TABLE ' . self::$cache_table);
        return true;
    }

    /**
     * 删除一条缓存记录
     * @param     $key
     * @param int $timeout 删除该元素的超时时间。
     *
     * @return bool
     */
    public function delete ($key, $timeout = 0) {
        $key .= $this->key_life_tag;
        $this->db->query('DELETE FROM ' . self::$cache_table . ' WHERE c_key="' . md5($key) . '" ');
        return true;
    }

    /**
     * 增加元素
     * @todo 未完成
     */
    public function increment ($key , $value = 1) {

    }

    /**
     * 减少元素的值
     * @todo 未完成
     */
    public function decrement ($key, $value = 1) {

    }

    /**
     * 取得当前缓存的类型名称
     * @return string
     */
    public function getType() {
        return 'Mysql';
    }
}